import React, { createContext, useContext, useEffect, useRef, useState } from "react";
import "./radio-group.scss"
import { getId } from "../../utils/commonUtil";

const Value = createContext<any>({})
const sizeArr = ['small', 'large']

/**
 * @param size 单选框尺寸
 * @param disabled 是否禁用
 * @param defaultValue 初始值
 * @param children 插槽
 * @param change 改变值时触发函数
 */
interface GroupProps {
    size?: 'default' | 'large' | 'small',
    disabled?: boolean,
    defaultValue?: string | number,
    value?: string | number,
    children?: React.ReactNode,
    change?: (value: string | number) => void
}

const RadioGroup = ({ size = "default", disabled = false, defaultValue = "", value = "", children, change = () => { } }: GroupProps) => {
    const [modelValue, setModelValue] = useState<string | number>(defaultValue)
    const [id] = useState<string>(`pe-radio-${getId()}`)

    const radioGroupRef = useRef<HTMLDivElement>(null)

    const [radioSize, setRadioSize] = useState<'default' | 'large' | 'small'>(size)
    const [radioDisabled, setRadioDisabled] = useState<boolean>(false)

    useEffect(() => {
        setRadioSize(size)
        setRadioDisabled(disabled)
        setModelValue(value)
    }, [size, disabled, value])

    return (
        <div ref={radioGroupRef} className="pe-radio-group" id={id}>
            <Value.Provider value={{ id, modelValue, setModelValue, radioSize, radioDisabled, change }}>
                {children}
            </Value.Provider>
        </div>
    )
}

/**
 * @param label 单选框的 label 
 * @param value 单选框的值
 * @param size 单选框的尺寸
 * @param disabled 是否禁用单选框
 * @param border 是否显示边框
 * @param name 原生 name 属性
 */
interface RadioProps {
    label?: string | number,
    value: string | number,
    size?: 'default' | 'large' | 'small',
    disabled?: boolean,
    border?: boolean,
    name?: string,
    children?: React.ReactNode
}

const Radio = ({ label, value, size, disabled, border = false, name, children }: RadioProps) => {
    const { id, modelValue, setModelValue, radioSize, radioDisabled, change } = useContext(Value)

    const getSize = () => {
        if (size) {
            return size
        }
        return radioSize
    }

    const getDisabled = () => {
        return typeof disabled === 'boolean' ? disabled : radioDisabled
    }

    return (
        <label
            className={["pe-radio", border ? 'pe-radio-border' : '', sizeArr.includes(getSize()) ? `pe-radio-${getSize()}` : '', getDisabled() ? 'pe-radio-disabled' : '', modelValue === value && !getDisabled() ? 'pe-radio-active' : ''].join(" ").trim()}>
            <div className={["pe-radio-item", modelValue === value ? 'pe-radio-checked' : ''].join(" ").trim()}>
                <input className="pe-radio-inp" type="radio" v-model="modelValue" value={value}
                    name={name ? name : id} disabled={getDisabled()}
                    onChange={() => {
                        setModelValue(value)
                        change(value)
                    }} />
                <div className="pe-radio-cir"></div>
            </div>
            <div style={{ color: modelValue === value && !getDisabled() ? 'var(--pe-color-primary)' : '' }}>
                {
                    children || children === 0 ? (<>{children}</>) : (<>{label}</>)
                }
            </div>
        </label>
    )
}

/**
 * @param label 单选框的 label
 * @param value 单选框的值
 * @param disabled 是否禁用单选框
 * @param name input 原生 name 属性
 */
interface ButtonProps {
    label?: string | number,
    value: string | number,
    disabled?: boolean,
    name?: string,
    children?: React.ReactNode
}

const RadioButton = ({ label, value, disabled = false, name, children }: ButtonProps) => {
    const { id, modelValue, setModelValue, radioSize, radioDisabled, change } = useContext(Value)

    const getDisabled = () => {
        return typeof disabled === 'boolean' ? disabled : radioDisabled
    }

    return (
        <label className={["pe-radio-button", modelValue === value && !getDisabled() ? 'pe-radio-button-active' : '', sizeArr.includes(radioSize) ? `pe-radio-button-${radioSize}` : '', getDisabled() ? 'pe-radio-button-disabled' : ''].join(" ").trim()}>
            <input className="pe-radio-inp" type="radio" v-model="modelValue" value={value} name={name ? name : id}
                disabled={getDisabled()}
                onChange={() => {
                    setModelValue(value)
                    change(value)
                }} />
            <div>
                {
                    children || children === 0 ? <>{children}</> : <>{label}</>
                }
            </div>
        </label>
    )
}

export { RadioGroup, Radio, RadioButton }